package com.atguigu.tingshu.search.receiver;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.search.service.ItemService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Component
@Slf4j
public class SearchAlbumReceiver {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ItemService itemService;

    private Long count = 0L;

    /**
     * 上架专辑到ES
     *
     * @param albumIdString
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_ALBUM, durable = "true"),
            value = @Queue(value = MqConst.QUEUE_ALBUM_UPPER, durable = "true"),
            key = MqConst.ROUTING_ALBUM_UPPER)
    )
    @SneakyThrows
    public void listenAlbumUpper(String albumIdString, Message message, Channel channel) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (!StringUtils.hasText(albumIdString)) {
            log.error("网络异常 未收到消息内容");
            return;
        }
        // 增加声音的播放量
        Long albumId = JSONObject.parseObject(albumIdString, Long.class);
        try {
            itemService.albumOnSale(albumId);
            // 如果未发生异常 则ack 若此处发生异常 则尝试重新入队消费 次数为三次
            channel.basicAck(deliveryTag, false);// 若在此处发生异常 则说明消息业务已经执行 但未能成功确认消息 需要手动确认
        } catch (IOException e) {
            channel.basicNack(deliveryTag, false, false);// 手动将消息丢掉
            log.error("网络异常{}", e.getMessage());
        } catch (GuiguException e) {
            // 如果来到此处 说明业务 执行失败 尝试重新入队消费
            // MD5防重一下
            String entry = "track:update" + albumId;
            count = redisTemplate.opsForValue().increment(entry);
            if (count >= 3) {
                redisTemplate.delete(entry);
                channel.basicNack(deliveryTag, false, false);
                log.error("上架专辑到ES服务端异常,id:{}", albumId);
            } else {
                channel.basicNack(deliveryTag, false, true);// 重新入队
                log.info("专辑id:{} 重新入队,次数为{}次", albumId, count);
            }
        }
    }

    /**
     * 从ES下架专辑
     *
     * @param albumIdString
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_ALBUM, durable = "true"),
            value = @Queue(value = MqConst.QUEUE_ALBUM_LOWER, durable = "true"),
            key = MqConst.ROUTING_ALBUM_LOWER)
    )
    @SneakyThrows
    public void listenAlbumLower(String albumIdString, Message message, Channel channel) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (!StringUtils.hasText(albumIdString)) {
            log.error("网络异常 未收到消息内容");
            return;
        }
        Long albumId = JSONObject.parseObject(albumIdString, Long.class);
        // 增加声音的播放量
        itemService.albumOffSale(albumId);
        try {
            // 如果未发生异常 则ack 若此处发生异常 则尝试重新入队消费 次数为三次
            channel.basicAck(deliveryTag, false);// 若在此处发生异常 则说明消息业务已经执行 但未能成功确认消息 需要手动确认
        } catch (IOException e) {
            channel.basicNack(deliveryTag, false, false);// 手动将消息丢掉
            log.error("网络异常{}", e.getMessage());
        } catch (GuiguException e) {
            // 如果来到此处 说明业务 执行失败 尝试重新入队消费
            // MD5防重一下
            String entry = "track:update" + albumId;
            count = redisTemplate.opsForValue().increment(entry);
            if (count >= 3) {
                redisTemplate.delete(entry);
                channel.basicNack(deliveryTag, false, false);
                log.error("下架专辑到ES服务端异常,id:{}", albumId);
            } else {
                channel.basicNack(deliveryTag, false, true);// 重新入队
                log.info("专辑id:{} 重新入队,次数为{}次", albumId, count);
            }
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_ALBUM_STAT_ES, durable = "true"),
            value = @Queue(value = MqConst.QUEUE_ALBUM_STAT_ES, durable = "true"),
            key = MqConst.ROUTING_ALBUM_STAT_ES)
    )
    @SneakyThrows
    public void listenAlbumPaidStatus(String jsonObjectStr, Message message, Channel channel) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (!StringUtils.hasText(jsonObjectStr)) {
            log.error("网络异常 未收到消息内容");
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonObjectStr, JSONObject.class);
        String orderNo = (String) jsonObject.get("orderNo");
        String userId = (String) jsonObject.get("userId");
        itemService.albumStatusUpdate(orderNo, Long.parseLong(userId));
        // 如果未发生异常 则ack 若此处发生异常 则尝试重新入队消费 次数为三次
        channel.basicAck(deliveryTag, false);// 若在此处发生异常 则说明消息业务已经执行 但未能成功确认消息 需要手动确认

    }
}
